//! 集群配置管理模块

use crate::manager::ClusterManager;
use crate::sync::DataSyncManager;
use nacos_core::{Result, NacosError};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use chrono::{DateTime, Utc};
use tracing::{info, error};
use uuid::Uuid;

/// 配置变更类型
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum ConfigChangeType {
    /// 添加配置
    Add,
    /// 更新配置
    Update,
    /// 删除配置
    Delete,
    /// 重载配置
    Reload,
}

/// 配置项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClusterConfigItem {
    /// 配置键
    pub key: String,
    /// 配置值
    pub value: String,
    /// 配置描述
    pub description: String,
    /// 配置类型
    pub config_type: ConfigType,
    /// 是否动态可更新
    pub dynamic: bool,
    /// 最后更新时间
    pub last_updated: DateTime<Utc>,
    /// 更新来源
    pub updated_by: String,
    /// 版本号
    pub version: u64,
}

/// 配置类型
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum ConfigType {
    /// 字符串
    String,
    /// 整数
    Integer,
    /// 浮点数
    Float,
    /// 布尔值
    Boolean,
    /// JSON对象
    Json,
    /// 列表
    List,
}

/// 配置变更事件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigChangeEvent {
    /// 事件ID
    pub event_id: String,
    /// 变更类型
    pub change_type: ConfigChangeType,
    /// 配置键
    pub key: String,
    /// 旧值
    pub old_value: Option<String>,
    /// 新值
    pub new_value: Option<String>,
    /// 变更时间
    pub change_time: DateTime<Utc>,
    /// 变更来源
    pub changed_by: String,
    /// 是否需要重启
    pub requires_restart: bool,
}

/// 集群配置管理器
#[derive(Debug)]
pub struct ClusterConfigManager {
    /// 集群管理器
    cluster_manager: Arc<ClusterManager>,
    /// 数据同步管理器
    data_sync_manager: Arc<DataSyncManager>,
    /// 本地配置存储
    local_config: Arc<RwLock<HashMap<String, ClusterConfigItem>>>,
    /// 配置变更监听器
    listeners: Arc<RwLock<Vec<Box<dyn ConfigChangeListener>>>>,
    /// 默认配置
    default_config: Arc<RwLock<HashMap<String, String>>>,
    /// 配置验证器
    validators: Arc<RwLock<HashMap<String, Box<dyn ConfigValidator>>>>,
}

/// 配置变更监听器trait
#[async_trait::async_trait]
pub trait ConfigChangeListener: Send + Sync + std::fmt::Debug {
    /// 配置变更回调
    async fn on_config_change(&self, event: &ConfigChangeEvent) -> Result<()>;
    /// 监听配置键
    fn listen_keys(&self) -> Vec<String>;
}

/// 配置验证器trait
#[async_trait::async_trait]
pub trait ConfigValidator: Send + Sync + std::fmt::Debug {
    /// 验证配置值
    async fn validate(&self, key: &str, value: &str) -> Result<()>;
    /// 获取验证规则描述
    fn validation_rule(&self) -> String;
}

impl ClusterConfigManager {
    /// 创建新的配置管理器
    pub fn new(
        cluster_manager: Arc<ClusterManager>,
        data_sync_manager: Arc<DataSyncManager>,
    ) -> Self {
        let mut default_config = HashMap::new();
        
        // 设置默认配置
        default_config.insert("heartbeat.interval".to_string(), "5000".to_string());
        default_config.insert("heartbeat.timeout".to_string(), "30000".to_string());
        default_config.insert("election.timeout".to_string(), "5000".to_string());
        default_config.insert("sync.batch.size".to_string(), "100".to_string());
        default_config.insert("sync.retry.count".to_string(), "3".to_string());
        default_config.insert("log.level".to_string(), "info".to_string());
        default_config.insert("max.connections".to_string(), "1000".to_string());
        default_config.insert("request.timeout".to_string(), "5000".to_string());

        Self {
            cluster_manager,
            data_sync_manager,
            local_config: Arc::new(RwLock::new(HashMap::new())),
            listeners: Arc::new(RwLock::new(Vec::new())),
            default_config: Arc::new(RwLock::new(default_config)),
            validators: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// 初始化配置管理器
    pub async fn initialize(&self) -> Result<()> {
        // 加载默认配置
        self.load_default_config().await?;
        
        // 注册内置验证器
        self.register_builtin_validators().await?;
        
        // 从集群同步配置
        self.sync_config_from_cluster().await?;
        
        info!("Cluster config manager initialized");
        Ok(())
    }

    /// 设置配置值
    pub async fn set_config(
        &self,
        key: String,
        value: String,
        description: Option<String>,
        source: String,
    ) -> Result<()> {
        // 验证配置
        self.validate_config(&key, &value).await?;

        // 检查是否为动态配置
        let is_dynamic = self.is_dynamic_config(&key).await;
        let requires_restart = !is_dynamic;

        // 获取旧值
        let old_value = self.get_config(&key).await?;

        // 创建配置项
        let config_item = ClusterConfigItem {
            key: key.clone(),
            value: value.clone(),
            description: description.unwrap_or_else(|| "No description".to_string()),
            config_type: self.guess_config_type(&value),
            dynamic: is_dynamic,
            last_updated: Utc::now(),
            updated_by: source.clone(),
            version: self.get_next_version(&key).await,
        };

        // 存储配置
        {
            let mut config = self.local_config.write().await;
            config.insert(key.clone(), config_item);
        }

        // 创建变更事件
        let event = ConfigChangeEvent {
            event_id: Uuid::new_v4().to_string(),
            change_type: if old_value.is_none() { 
                ConfigChangeType::Add 
            } else { 
                ConfigChangeType::Update 
            },
            key: key.clone(),
            old_value,
            new_value: Some(value),
            change_time: Utc::now(),
            changed_by: source,
            requires_restart,
        };

        // 同步到集群
        self.sync_config_to_cluster(&event).await?;

        // 触发监听器
        self.notify_listeners(&event).await?;

        Ok(())
    }

    /// 获取配置值
    pub async fn get_config(&self, key: &str) -> Result<Option<String>> {
        let local_config = self.local_config.read().await;
        
        if let Some(item) = local_config.get(key) {
            return Ok(Some(item.value.clone()));
        }

        let default_config = self.default_config.read().await;
        if let Some(value) = default_config.get(key) {
            return Ok(Some(value.clone()));
        }

        Ok(None)
    }

    /// 获取所有配置
    pub async fn get_all_config(&self) -> Result<HashMap<String, String>> {
        let local_config = self.local_config.read().await;
        let default_config = self.default_config.read().await;
        
        let mut result = HashMap::new();
        
        // 添加默认配置
        result.extend(default_config.clone());
        
        // 覆盖本地配置
        for (key, item) in local_config.iter() {
            result.insert(key.clone(), item.value.clone());
        }

        Ok(result)
    }

    /// 获取配置详情
    pub async fn get_config_details(&self, key: &str) -> Result<Option<ClusterConfigItem>> {
        let local_config = self.local_config.read().await;
        Ok(local_config.get(key).cloned())
    }

    /// 删除配置
    pub async fn delete_config(&self, key: &str, source: String) -> Result<()> {
        let old_value = self.get_config(key).await?;
        
        if old_value.is_none() {
            return Err(NacosError::NotFound(key.to_string()));
        }

        // 检查是否为内置配置
        if self.is_builtin_config(key).await {
            return Err(NacosError::Validation(
                "Cannot delete built-in configuration".to_string()
            ));
        }

        // 从本地配置中删除
        {
            let mut config = self.local_config.write().await;
            config.remove(key);
        }

        // 创建变更事件
        let event = ConfigChangeEvent {
            event_id: Uuid::new_v4().to_string(),
            change_type: ConfigChangeType::Delete,
            key: key.to_string(),
            old_value,
            new_value: None,
            change_time: Utc::now(),
            changed_by: source,
            requires_restart: true,
        };

        // 同步到集群
        self.sync_config_to_cluster(&event).await?;

        // 触发监听器
        self.notify_listeners(&event).await?;

        Ok(())
    }

    /// 注册配置变更监听器
    pub async fn register_listener(&self, listener: Box<dyn ConfigChangeListener>) -> Result<()> {
        let mut listeners = self.listeners.write().await;
        listeners.push(listener);
        Ok(())
    }

    /// 注册配置验证器
    pub async fn register_validator(
        &self,
        key: String,
        validator: Box<dyn ConfigValidator>,
    ) -> Result<()> {
        let mut validators = self.validators.write().await;
        validators.insert(key, validator);
        Ok(())
    }

    /// 批量更新配置
    pub async fn batch_update_config(
        &self,
        configs: Vec<(String, String, Option<String>)>,
        source: String,
    ) -> Result<Vec<Result<()>>> {
        let mut results = Vec::new();

        for (key, value, description) in configs {
            let result = self.set_config(key, value, description, source.clone()).await;
            results.push(result);
        }

        Ok(results)
    }

    /// 重载配置
    pub async fn reload_config(&self, source: String) -> Result<()> {
        // 创建重载事件
        let event = ConfigChangeEvent {
            event_id: Uuid::new_v4().to_string(),
            change_type: ConfigChangeType::Reload,
            key: "*".to_string(),
            old_value: None,
            new_value: None,
            change_time: Utc::now(),
            changed_by: source,
            requires_restart: false,
        };

        // 同步到集群
        self.sync_config_to_cluster(&event).await?;

        // 触发监听器
        self.notify_listeners(&event).await?;

        Ok(())
    }

    /// 获取配置快照
    pub async fn get_config_snapshot(&self) -> Result<ConfigSnapshot> {
        let config = self.get_all_config().await?;
        let local_details = self.local_config.read().await;
        
        Ok(ConfigSnapshot {
            timestamp: Utc::now(),
            config_count: config.len(),
            local_config_count: local_details.len(),
            config_hash: self.calculate_config_hash(&config),
            configs: config,
        })
    }

    /// 验证配置
    async fn validate_config(&self, key: &str, value: &str) -> Result<()> {
        let validators = self.validators.read().await;
        
        if let Some(validator) = validators.get(key) {
            validator.validate(key, value).await?;
        }

        // 类型验证
        match self.guess_config_type(value) {
            ConfigType::Integer => {
                value.parse::<i64>()
                    .map_err(|_| NacosError::Validation(
                        format!("Invalid integer value: {}", value)
                    ))?;
            }
            ConfigType::Float => {
                value.parse::<f64>()
                    .map_err(|_| NacosError::Validation(
                        format!("Invalid float value: {}", value)
                    ))?;
            }
            ConfigType::Boolean => {
                if value != "true" && value != "false" {
                    return Err(NacosError::Validation(
                        format!("Invalid boolean value: {}", value)
                    ));
                }
            }
            _ => {}
        }

        Ok(())
    }

    /// 检查是否为动态配置
    async fn is_dynamic_config(&self, key: &str) -> bool {
        let dynamic_keys = [
            "heartbeat.interval",
            "log.level",
            "max.connections",
            "request.timeout",
        ];

        dynamic_keys.contains(&key)
    }

    /// 检查是否为内置配置
    async fn is_builtin_config(&self, key: &str) -> bool {
        let builtin_keys = [
            "cluster.name",
            "node.id",
            "election.timeout",
        ];

        builtin_keys.contains(&key)
    }

    /// 猜测配置类型
    fn guess_config_type(&self, value: &str) -> ConfigType {
        if value == "true" || value == "false" {
            ConfigType::Boolean
        } else if value.parse::<i64>().is_ok() {
            ConfigType::Integer
        } else if value.parse::<f64>().is_ok() {
            ConfigType::Float
        } else if value.starts_with('{') && value.ends_with('}') {
            ConfigType::Json
        } else if value.contains(',') {
            ConfigType::List
        } else {
            ConfigType::String
        }
    }

    /// 获取下一个版本号
    async fn get_next_version(&self, key: &str) -> u64 {
        let local_config = self.local_config.read().await;
        if let Some(item) = local_config.get(key) {
            item.version + 1
        } else {
            1
        }
    }

    /// 加载默认配置
    async fn load_default_config(&self) -> Result<()> {
        let mut local_config = self.local_config.write().await;
        
        // 添加默认配置项
        let default_configs = vec![
            ClusterConfigItem {
                key: "heartbeat.interval".to_string(),
                value: "5000".to_string(),
                description: "心跳间隔时间(毫秒)".to_string(),
                config_type: ConfigType::Integer,
                dynamic: true,
                last_updated: Utc::now(),
                updated_by: "system".to_string(),
                version: 1,
            },
            ClusterConfigItem {
                key: "heartbeat.timeout".to_string(),
                value: "30000".to_string(),
                description: "心跳超时时间(毫秒)".to_string(),
                config_type: ConfigType::Integer,
                dynamic: true,
                last_updated: Utc::now(),
                updated_by: "system".to_string(),
                version: 1,
            },
            ClusterConfigItem {
                key: "election.timeout".to_string(),
                value: "5000".to_string(),
                description: "选举超时时间(毫秒)".to_string(),
                config_type: ConfigType::Integer,
                dynamic: false,
                last_updated: Utc::now(),
                updated_by: "system".to_string(),
                version: 1,
            },
        ];

        for config in default_configs {
            local_config.insert(config.key.clone(), config);
        }

        Ok(())
    }

    /// 注册内置验证器
    async fn register_builtin_validators(&self) -> Result<()> {
        // 注册整数验证器
        self.register_validator(
            "heartbeat.interval".to_string(),
            Box::new(IntegerRangeValidator::new(1000, 60000)),
        ).await?;

        self.register_validator(
            "heartbeat.timeout".to_string(),
            Box::new(IntegerRangeValidator::new(5000, 300000)),
        ).await?;

        self.register_validator(
            "max.connections".to_string(),
            Box::new(IntegerRangeValidator::new(100, 10000)),
        ).await?;

        Ok(())
    }

    /// 从集群同步配置
    async fn sync_config_from_cluster(&self) -> Result<()> {
        // 实际实现中会从集群领导者同步配置
        info!("Syncing configuration from cluster leader");
        Ok(())
    }

    /// 同步配置到集群
    async fn sync_config_to_cluster(&self, event: &ConfigChangeEvent) -> Result<()> {
        // 使用数据同步管理器同步配置变更
        let config_data = serde_json::to_vec(&event)
            .map_err(NacosError::from)?;

        self.data_sync_manager.store_data(
            "cluster".to_string(),
            "config".to_string(),
            event.key.clone(),
            config_data,
            event.changed_by.clone(),
        ).await?;

        Ok(())
    }

    /// 通知监听器
    async fn notify_listeners(&self, event: &ConfigChangeEvent) -> Result<()> {
        let listeners = self.listeners.read().await;
        
        for listener in listeners.iter() {
            let listen_keys = listener.listen_keys();
            
            if listen_keys.contains(&"*".to_string()) || listen_keys.contains(&event.key) {
                if let Err(e) = listener.on_config_change(event).await {
                    error!("Failed to notify listener: {}", e);
                }
            }
        }

        Ok(())
    }

    /// 计算配置哈希
    fn calculate_config_hash(&self, config: &HashMap<String, String>) -> u64 {
        use std::hash::{Hash, Hasher};
        use std::collections::hash_map::DefaultHasher;
        
        let mut hasher = DefaultHasher::new();
        for (key, value) in config {
            key.hash(&mut hasher);
            value.hash(&mut hasher);
        }
        hasher.finish()
    }
}

/// 配置快照
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigSnapshot {
    /// 时间戳
    pub timestamp: DateTime<Utc>,
    /// 配置总数
    pub config_count: usize,
    /// 本地配置数
    pub local_config_count: usize,
    /// 配置哈希值
    pub config_hash: u64,
    /// 配置内容
    pub configs: HashMap<String, String>,
}

/// 整数范围验证器
#[derive(Debug)]
pub struct IntegerRangeValidator {
    min: i64,
    max: i64,
}

impl IntegerRangeValidator {
    pub fn new(min: i64, max: i64) -> Self {
        Self { min, max }
    }
}

#[async_trait::async_trait]
impl ConfigValidator for IntegerRangeValidator {
    async fn validate(&self, _key: &str, value: &str) -> Result<()> {
        let int_value = value.parse::<i64>()
            .map_err(|_| NacosError::Validation(
                format!("Invalid integer: {}", value)
            ))?;

        if int_value < self.min || int_value > self.max {
            return Err(NacosError::Validation(
                format!("Value must be between {} and {}", self.min, self.max)
            ));
        }

        Ok(())
    }

    fn validation_rule(&self) -> String {
        format!("Integer value between {} and {}", self.min, self.max)
    }
}

/// 正则表达式验证器
#[derive(Debug)]
pub struct RegexValidator {
    pattern: String,
    regex: regex::Regex,
}

impl RegexValidator {
    pub fn new(pattern: &str) -> Result<Self> {
        let regex = regex::Regex::new(pattern)
            .map_err(|e| NacosError::Validation(e.to_string()))?;
        
        Ok(Self {
            pattern: pattern.to_string(),
            regex,
        })
    }
}

#[async_trait::async_trait]
impl ConfigValidator for RegexValidator {
    async fn validate(&self, _key: &str, value: &str) -> Result<()> {
        if !self.regex.is_match(value) {
            return Err(NacosError::Validation(
                format!("Value must match pattern: {}", self.pattern)
            ));
        }
        Ok(())
    }

    fn validation_rule(&self) -> String {
        format!("Must match regex pattern: {}", self.pattern)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::manager::{ClusterConfig, ClusterManager};
    use crate::sync::DataSyncManager;

    #[tokio::test]
    async fn test_config_manager() {
        let config = ClusterConfig::default();
        let cluster_manager = Arc::new(ClusterManager::new(config));
        let data_sync_manager = Arc::new(DataSyncManager::new(
            cluster_manager.clone(),
            3,
            100,
        ));

        let config_manager = ClusterConfigManager::new(
            cluster_manager,
            data_sync_manager,
        );

        config_manager.initialize().await.unwrap();

        // 测试设置配置
        config_manager.set_config(
            "test.key".to_string(),
            "test_value".to_string(),
            Some("Test configuration".to_string()),
            "test_user".to_string(),
        ).await.unwrap();

        // 测试获取配置
        let value = config_manager.get_config("test.key").await.unwrap();
        assert_eq!(value, Some("test_value".to_string()));

        // 测试获取默认配置
        let heartbeat = config_manager.get_config("heartbeat.interval").await.unwrap();
        assert_eq!(heartbeat, Some("5000".to_string()));
    }

    #[tokio::test]
    async fn test_config_validation() {
        let config = ClusterConfig::default();
        let cluster_manager = Arc::new(ClusterManager::new(config));
        let data_sync_manager = Arc::new(DataSyncManager::new(
            cluster_manager.clone(),
            3,
            100,
        ));

        let config_manager = ClusterConfigManager::new(
            cluster_manager,
            data_sync_manager,
        );

        config_manager.initialize().await.unwrap();

        // 测试有效整数
        let result = config_manager.set_config(
            "heartbeat.interval".to_string(),
            "3000".to_string(),
            None,
            "test".to_string(),
        ).await;
        assert!(result.is_ok());

        // 测试无效整数
        let result = config_manager.set_config(
            "heartbeat.interval".to_string(),
            "invalid".to_string(),
            None,
            "test".to_string(),
        ).await;
        assert!(result.is_err());

        // 测试范围验证
        let result = config_manager.set_config(
            "heartbeat.interval".to_string(),
            "999".to_string(),
            None,
            "test".to_string(),
        ).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_config_deletion() {
        let config = ClusterConfig::default();
        let cluster_manager = Arc::new(ClusterManager::new(config));
        let data_sync_manager = Arc::new(DataSyncManager::new(
            cluster_manager.clone(),
            3,
            100,
        ));

        let config_manager = ClusterConfigManager::new(
            cluster_manager,
            data_sync_manager,
        );

        config_manager.initialize().await.unwrap();

        // 设置配置
        config_manager.set_config(
            "delete.test".to_string(),
            "value".to_string(),
            None,
            "test".to_string(),
        ).await.unwrap();

        // 验证配置存在
        let value = config_manager.get_config("delete.test").await.unwrap();
        assert_eq!(value, Some("value".to_string()));

        // 删除配置
        config_manager.delete_config("delete.test", "test".to_string()).await.unwrap();

        // 验证配置已删除
        let value = config_manager.get_config("delete.test").await.unwrap();
        assert_eq!(value, None);
    }

    #[tokio::test]
    async fn test_config_snapshot() {
        let config = ClusterConfig::default();
        let cluster_manager = Arc::new(ClusterManager::new(config));
        let data_sync_manager = Arc::new(DataSyncManager::new(
            cluster_manager.clone(),
            3,
            100,
        ));

        let config_manager = ClusterConfigManager::new(
            cluster_manager,
            data_sync_manager,
        );

        config_manager.initialize().await.unwrap();

        // 设置一些配置
        config_manager.set_config(
            "snapshot.test1".to_string(),
            "value1".to_string(),
            None,
            "test".to_string(),
        ).await.unwrap();

        config_manager.set_config(
            "snapshot.test2".to_string(),
            "value2".to_string(),
            None,
            "test".to_string(),
        ).await.unwrap();

        // 获取快照
        let snapshot = config_manager.get_config_snapshot().await.unwrap();
        assert!(snapshot.config_count >= 2);
        assert!(snapshot.configs.contains_key("snapshot.test1"));
        assert!(snapshot.configs.contains_key("snapshot.test2"));
    }
}